#include <stdio.h>
#include <iwlib.h>

/*
\u2022 Status : Its current state. This is a device dependent information.
\u2022 Quality - link : general quality of the reception.
\u2022 Quality - level : signal strength at the receiver.
\u2022 Quality - noise : silence level (no packet) at the receiver.
\u2022 Discarded - nwid : number of discarded packets due to invalid network id.
\u2022 Discarded - crypt : number of packet unable to decrypt.
\u2022 Discarded - misc : unused (for now).
These informations allow the user to have a better feedback about his system.
A high value of Discarded - nwid packet might indicate a nwid configuration
problem or an adjacent network. The Quality - level might help him to track
shadow areas.
The basic difference between Quality - link and Quality - level is that the first
indicate how good the reception is (for example the percentage of correctly received
packets) and the second how strong the signal is. The Quality - level is some
directly measurable data that is likely to have the same signification across
devices.
When the Quality values have been updated since the last read of the entry,
a dot will follow that value (typically, it mean that a new measure has been made).
*/

/* Value was updated since last read */
/*
#define IW_QUAL_QUAL_UPDATED    0x1     
#define IW_QUAL_LEVEL_UPDATED   0x2
#define IW_QUAL_NOISE_UPDATED   0x4
*/
/* Driver doesn't provide value */
/*
#define IW_QUAL_QUAL_INVALID    0x10    
#define IW_QUAL_LEVEL_INVALID   0x20
#define IW_QUAL_NOISE_INVALID   0x40
*/

/* it's not a good indicator for checking the quality of the network */
/* it depends in the driver implementation ( not good ) */
int __get_wireless_quality(char *ifname)
{

	int skfd;
	int has_range;
	iwstats stats;
	iwrange range;
	int res;

	/* Create a channel to the NET kernel. */
	if((skfd = iw_sockets_open()) < 0){
		perror("socket");
		return -1;
	}

	 /* Get range stuff */
	 has_range = (iw_get_range_info(skfd, ifname, &range) >= 0);

	 res = iw_get_stats(skfd, ifname, &stats, &range, has_range);
	 if (res < 0) {
		 fprintf(stderr, "Error getting stats\n");
	 }

	 /* Close the socket. */
	 iw_sockets_close(skfd);

	 if (stats.qual.updated == IW_QUAL_QUAL_INVALID)
		 printf("Quality doesn't provide\n");
	 if (stats.qual.updated == IW_QUAL_LEVEL_INVALID)
		 printf("Level doesn't provide\n");
	 if (stats.qual.updated == IW_QUAL_NOISE_INVALID)
		 printf("Noise doesn't provide\n");

	 if (stats.qual.updated == IW_QUAL_QUAL_UPDATED)
		 printf("Quality not updated\n");
	 if (stats.qual.updated == IW_QUAL_LEVEL_UPDATED)
		 printf("Level not updated\n");
	 if (stats.qual.updated == IW_QUAL_NOISE_UPDATED)
		 printf("Noise not updated\n");

	 printf("link quality: %d - ", stats.qual.qual);
	 printf("signal level: %d - ", stats.qual.level);
	 printf("noise level : %d \n", stats.qual.noise);

	 return 0;

}


int main(int argc, char **argv)
{
	if (argc != 2) {
		printf("I need an interface name\n");
		return -1;
	}

	while(1){
		__get_wireless_quality(argv[1]);
		sleep(1);
	}

}
